#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include "world.h"
#include "mainmenu.h"
#include "player.h"
#include "hud.h"
#include "ai.h"

#define GS_MAIN_MENU 0
#define GS_SETUP 1
#define GS_GAME 1
#define GS_GAMEOVER 3
#define GS_CLOSE 4

int main()
{	
	unsigned char gameState = GS_MAIN_MENU;
	sf::RenderWindow app(sf::VideoMode(640, 480, 32), "Lafacukur");
	sf::Clock clock;
	sf::Event event;
	sf::Sprite* spBuff;
	MainMenu menu;
	World world;
	Player p1("Lafacukur", 1);
	Player p2("", 2);
	Player p3("", 3);
	Player p4("", 4);
	HUD hud;
	AI ai;
	while (app.IsOpened())
	{
		// clear display
		app.Clear();
		// handle input
		while(app.GetEvent(event))
		{
			if (event.Type == sf::Event::Closed) gameState = GS_CLOSE;
			if (event.Type == sf::Event::KeyPressed)
			{
				if (gameState == GS_MAIN_MENU && event.Key.Code == sf::Key::Down) menu.goDown();
				if (gameState == GS_MAIN_MENU && event.Key.Code == sf::Key::Up) menu.goUp();
				if (gameState == GS_MAIN_MENU && event.Key.Code == sf::Key::Space) 
				{
					gameState = menu.goEnter();
					if (gameState == GS_GAME)
					{
						hud.start();
						ai.registerAIControled(&p2, 1);
						ai.registerAIControled(&p3, 2);
						ai.registerAIControled(&p4, 3);						
						ai.setup();
					}
				}
				if (gameState == GS_GAME && event.Key.Code == sf::Key::Space && hud.getState() > HS_OFF)
				{
					if (p1.getState() < PS_SLOW)
					{
						p1.nextState();
						if (hud.getState() == HS_RED) p1.nextState();
					}
				}
			}
			if (gameState == GS_CLOSE) app.Close();
		}
		// update game states
		if (clock.GetElapsedTime() > 0.0166666f)
		{
			if (gameState == GS_GAME)
			{
				hud.update();
				if (hud.newRound())
				{
					if (hud.gameOver())
					{
						gameState = GS_GAMEOVER;
						continue;
					}
					p1.reset();
					p2.reset();
					p3.reset();
					p4.reset();
					ai.setup();
					world.reset();
					hud.reset();
					continue;				
				}				
				ai.update(hud.getState());							
				p1.update();
				p2.update();
				p3.update();
				p4.update();				
				world.update(p1.getHeight() + 200);								
			}
			clock.Reset();
		} 
		// draw
		if (gameState == GS_MAIN_MENU) while ((spBuff = menu.getSprite()) != NULL) app.Draw(*spBuff);
		if (gameState == GS_GAME)
		{
			while ((spBuff = world.getSprite()) != NULL) app.Draw(*spBuff);
			while ((spBuff = p1.getSprite(world.getHeight())) != NULL) app.Draw(*spBuff);
			while ((spBuff = p2.getSprite(world.getHeight())) != NULL) app.Draw(*spBuff);
			while ((spBuff = p3.getSprite(world.getHeight())) != NULL) app.Draw(*spBuff);
			while ((spBuff = p4.getSprite(world.getHeight())) != NULL) app.Draw(*spBuff);
			while ((spBuff = hud.getSprite(world.getHeight())) != NULL) app.Draw(*spBuff);
		}
		if (gameState == GS_GAMEOVER) ;
		// put all on display
		app.Display();
	}
	return 0;
}
